#include "cdisplay.h"
#include <QDebug>
#include <GL/glu.h>

CDisplay::CDisplay(QWidget *parent)
        : myQGLWidget(32, parent)
{
    this->m_RenderMode = GL_TRIANGLES;

    this->m_pCamera = NULL;
}

void CDisplay::initializeGL()
{
    glEnable(GL_LIGHTING);
    glEnable(GL_LIGHT0);

    glShadeModel(GL_SMOOTH);
    glClearColor(0.4f, 0.4f, 0.4f, 0.0f);
    glClearDepth(1.0f);
    glEnable(GL_DEPTH_TEST);
    glDepthFunc(GL_LEQUAL);
    glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST);
}

void CDisplay::resizeGL(int width, int height)
{
    if(height <= 0)
        height = 1;
    glViewport(0, 0, width, height);
    this->m_pCamera->m_uWindow_height = height;
    this->m_pCamera->m_uWindow_width = width;
    glMatrixMode(GL_PROJECTION);
    glLoadIdentity();

    gluPerspective(this->m_pCamera->m_fFovy, (GLfloat)width/(GLfloat)height, 0.1f, 50000.0f);
    glMatrixMode(GL_MODELVIEW);
    glLoadIdentity();
}

void CDisplay::paintGL()
{
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
    glLoadIdentity();

    this->m_pCamera->look();

    glDisable(GL_LIGHTING);
    glColor3ub(255, 0, 0);
    glBegin(GL_LINES);
        glVertex3f(0.0f, 0.0f, 0.0f);
                glVertex3f(10.0f, 0.0f, 0.0f);
    glEnd();

    glColor3ub(0, 255, 0);
    glBegin(GL_LINES);
        glVertex3f(0.0f, 0.0f, 0.0f);
                glVertex3f(0.0f, 10.0f, 0.0f);
    glEnd();

    glColor3ub(0, 0, 255);
    glBegin(GL_LINES);
        glVertex3f(0.0f, 0.0f, 0.0f);
                glVertex3f(0.0f, 0.0f, 10.0f);
    glEnd();
    glEnable(GL_LIGHTING);

    if (this->m_objects.size() > 0)
    {
        for(int i = 0; i < this->m_objects.size(); ++i)
        {
            this->m_objects[i]->paint();
        }
    }
}

void CDisplay::mousePressEvent(QMouseEvent *event)
{
    this->m_LastPos = event->pos();
}

void CDisplay::mouseMoveEvent(QMouseEvent *event)
{
    GLfloat dx = GLfloat(event->x()-this->m_LastPos.x())/this->width();
    GLfloat dy = GLfloat(event->y()-this->m_LastPos.y())/this->height();

    this->m_pCamera->m_fTheta -= dy*this->m_pCamera->m_fSensitivity;
    this->m_pCamera->m_fPhi -= dx*this->m_pCamera->m_fSensitivity;
    this->m_pCamera->VectorsFromAngles();

    /*if(event->buttons() & Qt::LeftButton)
    {
        this->rotationX += 180*dy;
        this->rotationY += 180*dx;
        this->rotationZ = 0;
        this->updateGL();
    }
    else if (event->buttons() & Qt::RightButton)
    {
        this->rotationX += 180*dy;
        this->rotationY = 0;
        this->rotationZ += 180*dx;
        this->updateGL();
    }
    else if (event->buttons() & Qt::MidButton)
    {
        GLfloat d = GLfloat(this->lastPos.y()) - event->y();
        if (d > 0)
        {
            this->eloign += 0.25;
        }
        else if (d < 0)
        {
            this->eloign -= 0.25;
        }
    }*/
    this->m_LastPos = event->pos();
}

void CDisplay::enterEvent(QEvent * event)
{
    QGLWidget::enterEvent(event);
    if (1)
    {
        this->setFocus();
        this->grabKeyboard();
    }
}

void CDisplay::keyPressEvent(QKeyEvent * keyEvent)
{
    if(keyEvent->key() == Qt::Key_Up)
        this->m_pCamera->m_Position += CPoint3f(this->m_pCamera->m_Up * this->m_pCamera->m_fSpeed);
    if(keyEvent->key() == Qt::Key_Down)
        this->m_pCamera->m_Position -= CPoint3f(this->m_pCamera->m_Up * this->m_pCamera->m_fSpeed);
    if(keyEvent->key() == Qt::Key_Left)
        this->m_pCamera->m_Position += CPoint3f(this->m_pCamera->m_Side * this->m_pCamera->m_fSpeed);
    if(keyEvent->key() == Qt::Key_Right)
        this->m_pCamera->m_Position -= CPoint3f(this->m_pCamera->m_Side * this->m_pCamera->m_fSpeed);
    if(keyEvent->key() == Qt::Key_A)
        this->m_pCamera->m_Position += CPoint3f((this->m_pCamera->m_Direction*(1.0f/this->m_pCamera->m_Direction.length())) * this->m_pCamera->m_fSpeed);
    if(keyEvent->key() == Qt::Key_Q)
        this->m_pCamera->m_Position -= CPoint3f((this->m_pCamera->m_Direction*(1.0f/this->m_pCamera->m_Direction.length())) * this->m_pCamera->m_fSpeed);
    this->m_pCamera->m_Target = this->m_pCamera->m_Position + this->m_pCamera->m_Direction;
}

void CDisplay::mouseDoubleClickEvent(QMouseEvent *event)
{
    if (!event)
        event = NULL;
}

void CDisplay::add_object(CDrawable* obj)
{
    this->m_objects.push_back(obj);
}

void CDisplay::set_render_mode(GLenum mode)
{
    this->m_RenderMode = mode;
}

void CDisplay::enable_lighting()
{
    glEnable(GL_LIGHTING);
}

void CDisplay::disable_lighting()
{
    glDisable(GL_LIGHTING);
}

